// 写在前面
// 特殊参数：
//  dateOnly：只有一个日期，prop照传
//  [prop]$disabled：当前字段是否可以可选
//  date：两个日期，对象字段固定分别为：startDate,endDate
//  date不可选则分别为：startDate$disabled,endDate$disabled
//  pic：图片参数默认为url，可以通过urlProp转化
//  mutex:提供简单的一对多的互斥功能
//  lineHeight:应对内容过长提供的压缩行高功能
//  dialogFormDisable: 是否禁用所有选项，同时去掉底部的取消确定按钮

<template>
  <el-dialog
    class="dialog-licence-box"
    :title="dialogFormObj.title || '证照'"
    :visible.sync="dialogPopupVisible"
    :width="dialogFormObj.width || '625px'"
    @close='closeDialog'
  >
    <slot name="header"/>
    <el-form
      ref="licenceFormRules"
      inline
      :disabled="dialogFormDisable"
      :label-width="dialogFormObj.labelWidth || '135px'"
      :model="formData"
    >
      <!-- 遍历列表 -->
      <div
        v-for="(item,index) in dialogFormObj.formStructure"
        :key="index">

        <!-- 时间选择配置 -->
        <span v-if="item.type == 'date'">
          <el-form-item
            :label="item.label"
            :class="{'line-height':item.lineHeight}"
            :prop="item.otherProp || 'startDate'"
            :show-message="!formData['startDate$disabled']"
            :rules="formData['startDate$disabled'] ? isRulesRequired : startDateRules"
          >
            <div
              class="date-picker">
              <el-date-picker
                :disabled="formData['startDate$disabled'] || false"
                v-model="formData.startDate"
                :type="item.type"
                :picker-options="pickerOptionsStart"
                value-format="timestamp"
                placeholder="开始日期"
              />
            </div>
          </el-form-item>
          <el-form-item>-</el-form-item>
          <el-form-item
            :prop="item.otherProp || 'endDate'"
            :show-message="!formData['endDate$disabled']"
            :rules="formData['endDate$disabled'] ? isRulesRequired : endDateRules">
            <div
              class="date-picker">
              <el-date-picker
                :disabled="formData['endDate$disabled'] || false"
                v-model="formData.endDate"
                :type="item.type"
                :picker-options="pickerOptionsEnd"
                value-format="timestamp"
                placeholder="结束日期"
              />
            </div>
          </el-form-item>
        </span>
        <div v-else-if="item.type == 'otherPic'">
          <el-form-item
            :label="item.label"
            :class="{'line-height':item.lineHeight}"
          >
            <div >
              <el-select
                v-model="formData.uploadFileType"
                @change="handleSelectChange">
                <el-option
                  v-for="item in otherPicTypeOptions"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"/>
              </el-select>
            </div>
          </el-form-item>
          <!--图片上传-->
          <el-form-item
            v-if="formData.uploadFileType == '2'"
            :prop="item.prop || 'imgUrlList'"
            :show-message="!formData['imgUrlList$disabled']"
            :rules="formData['imgUrlList$disabled'] ? isRulesRequired : otherPicRules"
          >
            <div >
              <input
                type="hidden"
                v-model="formData.imgUrlList" >
              <div
                v-if="formData.imgUrlList && formData.imgUrlList.length>0"
                class="imgUrlList-box">
                <div
                  class="box-item"
                  v-for="(item,index) in formData.imgUrlList">
                  <el-image
                    height="132px"
                    :src="item[0]"
                  />
                  <span class="box-item__item-actions">
                    <span class="box-item__item-delete">
                      <i
                        class="el-icon-delete"
                        @click="handleRemove(item,index)"/>
                    </span>
                  </span>
                </div>
              </div>
              <m-upload
                v-if="!dialogFormDisable"
                class="other-box dialog-upload"
                :action="uploadUrl"
                multiple
                :show-file-list="false"
                :accept="uploadAccept"
                :limit="50"
                :file-list="formData.imgUrlList"
                :on-exceed="handleExceed"
                :on-success="handleUploadSuccess"
                :m-props="{urlObj:formData,urlStr:'imgUrlList',type:formData.type,uploadFileType:formData.uploadFileType}"
                :before-upload="beforeUpload"
                :http-request="httpUpload"
              >
                <div
                  class="tip-box">
                  <div class="tip-uplader">
                    <i class="el-icon-plus avatar-uploader-icon" />
                  </div>
                  <p class="tip-font">{{ formData.url }}(支持jpg/png格式，{{ fileSize }}M以内，需加盖公章)</p>
                </div>
              </m-upload>
            </div>
          </el-form-item>
          <el-form-item
            v-else
            :prop="item.prop || 'url'"
            :show-message="!formData['url$disabled']"
            :rules="formData['url$disabled'] ? isRulesRequired : otherPicRules"
          >
            <div >
              <input
                type="hidden"
                v-model="formData.url" >
              <m-upload
                class="other-box dialog-upload"
                :action="uploadUrl"
                :show-file-list="false"
                :accept="uploadAccept"

                :on-success="handleUploadSuccess"
                :m-props="{urlObj:formData,urlStr:'url',type:formData.type,uploadFileType:formData.uploadFileType}"
                :before-upload="beforeUpload"
                :http-request="httpUpload"
              >
                <i
                  v-if="formData.url && formData.url.includes('pdf')"
                  class="iconfont iconpdf"/>
                <div
                  v-else
                  class="tip-box">
                  <div class="tip-uplader">
                    <i class="el-icon-plus avatar-uploader-icon" />
                  </div>
                  <p class="tip-font">{{ formData.url }}(支持/pdf格式，{{ fileSize }}M以内，需加盖公章)</p>
                </div>
              </m-upload>
            </div>
          </el-form-item>
        </div>
        <el-form-item
          v-else
          :label="item.label"
          :class="{'line-height':item.lineHeight}"
          :disabled="formData[item.prop + '$disabled']"
          hide-required-asterisk
          :prop="item.type === 'pic' ? (item.urlProp || 'url') : (item.otherProp || item.prop)"
          :show-message="!formData[item.prop + '$disabled']"
          :rules="formData[item.prop + '$disabled'] ? isRulesRequired : rulesMethod(item)">
          <!-- 未来考虑render优化，缺乏太多element属性 -->
          <!-- 输入框配置 -->
          <div v-if="item.type === 'input' || item.type === 'textarea'">
            <el-input
              :type="item.type"
              :maxlength="item.maxLength ? item.maxLength : 100"
              :disabled="formData[item.prop + '$disabled'] || false"
              v-model="formData[item.prop]"
              :placeholder="item.placeholder || '请输入'" />
          </div>
          <!-- 下拉框配置 -->
          <div v-else-if="item.type === 'select'">
            <el-select
              :disabled="formData[item.prop + '$disabled'] || false"
              v-model="formData[item.prop]"
              :placeholder="item.placeholder || '请选择'">
              <el-option
                v-for="item in item.option"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </div>
          <!-- 时间单个选择配置 -->
          <div v-else-if="item.type === 'dateOnly'">
            <el-date-picker
              :disabled="formData[item.prop + '$disabled'] || false"
              v-model="formData[item.prop]"
              type="date"
              value-format="timestamp"
              placeholder="开始日期"
            />
          </div>
          <!-- 图片上传 -->
          <div v-else-if="item.type === 'pic'">
            <!-- 使用中间标签处理报错提示 -->
            <input
              type="hidden"
              v-model="formData[item.prop]" >
            <m-upload
              class="dialog-upload"
              :action="uploadUrl"
              :show-file-list="false"
              :accept="uploadAccept"
              :on-success="handleUploadSuccess"
              :m-props="{urlObj:formData,urlStr:item.prop}"
              :before-upload="beforeUpload"
              :http-request="httpUpload"
            >
              <i
                v-if="formData.url && formData.url.includes('pdf')"
                class="iconfont iconpdf"/>
              <div
                v-else-if="formData.url"
                class="avatar-box">
                <el-image
                  :fit="fitType"
                  height="132px"
                  :src="formData.url"
                  class="avatar"
                />
              </div>
              <div
                v-else
                class="tip-box">
                <div class="tip-uplader">
                  <i class="el-icon-plus avatar-uploader-icon" />
                </div>
                <p class="tip-font">{{ formData.url }}(支持jpg/png/pdf格式，{{ fileSize }}M以内，需加盖公章)</p>
              </div>
            </m-upload>
          </div>
          <div v-else-if="item.type === 'slot'">
            <slot
              :name="item.prop"
              :formData="formData">这是插槽。。。</slot>
          </div>
        </el-form-item>

      </div>
    </el-form>
    <slot name="footer">
      <span
        slot="footer"
        v-if="!dialogFormDisable"
        class="dialog-footer">
        <el-button @click.stop="cancelHandel(formData.type)">取消</el-button>
        <el-button
          :loading="dialogBtnVisible"
          type="primary"
          @click.stop="submitHandle">确定</el-button>
      </span>
    </slot>
  </el-dialog>
</template>

<script>
  import { isArray, isUndefined } from 'lodash'
  import { fileUpload } from '@const/api.js'
  import { fitType } from '@const/common.js'
  const imageFileLimit = '.png,.jpg,.jpeg,.bpg,.pdf'
  export default {
    data () {
      return {
        fitType,
        imgIndex: 0,
        otherPicTypeOptions: [
          {
            label: '图片',
            value: '2'
          },
          {
            label: 'pdf',
            value: '1'
          }
        ],
        isRulesRequired: [],
        startDateRules: [{ required: true, message: '请选择开始日期', trigger: 'blur' }],
        endDateRules: [{ required: true, message: '请选择结束日期', trigger: 'blur' }],
        otherPicRules: [{
          required: true,
          message: '请输入证照附件',
          trigger: 'blur'
        }],
        dialogBtnVisible: false, // 确认按钮的loading
        dialogPopupVisible: this.dialogVisible, // 确认按钮的loading
        uploadUrl: fileUpload, // 上传的地址
        pickerOptionsStart: {
          disabledDate: time => {
            let endDateVal = this.formData.endDate
            if (endDateVal) {
              return time.getTime() > new Date(endDateVal).getTime()
            }
          }
        },
        pickerOptionsEnd: {
          disabledDate: time => {
            let beginDateVal = this.formData.startDate
            if (beginDateVal) {
              return (
                time.getTime() < new Date(beginDateVal).getTime() ||
                time.getTime() < Date.now() - 8.64e7
              )
            } else {
              return time.getTime() < Date.now()
            }
          }
        }
      }
    },
    watch: {
      dialogVisible: {
        handler (newValue) {
          this.dialogPopupVisible = newValue
        }
      },
      dialogPopupVisible: {
        handler (newValue) {
          !newValue && this.$emit('cancel-btn-handle')
          !newValue && this.$refs['licenceFormRules'] && this.$refs['licenceFormRules'].clearValidate()
          newValue && this.struckMethod()
        }
      }
    },
    props: {
      // dialog非表单的所有数据集合
      dialogFormObj: {
        type: Object,
        required: true,
        default: () => {}
      },
      // dialog表单数据
      formData: {
        type: Object,
        required: true,
        default: () => {}
      },
      // dialog的显隐
      dialogVisible: {
        type: Boolean,
        required: true,
        default: true
      },
      // 文件数量限制
      fileNum: {
        type: Number,
        required: false,
        default: 1
      },
      // 文件大小限制
      fileSize: {
        type: Number,
        required: false,
        default: 3
      },
      // 文件上传类型
      uploadAccept: {
        type: String,
        required: false,
        default: ''
      },
      // 里面的内容是否禁用
      dialogFormDisable: {
        type: Boolean,
        default: false
      }
    },
    methods: {
      handleRemove (obj, index) {
        this.formData.imgUrlList.splice(index, 1)
        for (var i = index; i < this.formData.imgUrlList.length; i++) {
          var item = this.formData.imgUrlList[i]
          item[1] = i.toString()
        }
        console.log(this.formData.imgUrlList);
      },
      handleExceed (files, fileList) {
        console.log(files)
        console.log(fileList)
        this.$message.error(`图片最多只能上传50张!`)
      },
      handleSelectChange () {
        this.formData.imgUrlList = []
        this.formData.url = ''
      },
      // 监听取反数据
      struckMethod () {
        this.dialogFormObj.formStructure.forEach(item => {
          if (item.mutex) {
            // 开启默认
            let defaultKey = '$disabled'
            if (this.formData[item.prop] === item.mutex[0]) {
              item.mutex[1].forEach(it => {
                let keyName = it + defaultKey
                this.formData[it] = ''
                isUndefined(this.formData[keyName])
                  ? this.$set(this.formData, keyName, true)
                  : this.formData[keyName] = true
              })
            } else {
              item.mutex[1].forEach(it => {
                let keyName = it + defaultKey
                isUndefined(this.formData[keyName])
                  ? this.$set(this.formData, keyName, false)
                  : this.formData[keyName] = false
              })
            }
            // 发起监听
            this.$watch(`formData.${[item.prop]}`, (newValue) => {
              if (newValue === item.mutex[0]) {
                item.mutex[1].forEach(it => {
                  let keyName = it + defaultKey
                  this.formData[it] = ''
                  this.formData[keyName] = true
                })
              } else {
                item.mutex[1].forEach(it => {
                  let keyName = it + defaultKey
                  this.formData[keyName] = false
                })
              }
            })
          }
        })
      },
      // 提供form-item规则返回
      rulesMethod (item) {
        if (item.required) {
          if (isArray(item.rules) && item.rules.length) {
            return item.rules.push({ required: true })
          } else {
            return [ { required: true } ]
          }
        } else {
          return item.rules || []
        }
      },
      // 提交按钮
      submitHandle () {
        // 时间校验
        this.$refs['licenceFormRules'].validate(valid => {
          if (valid) {
            console.log(this.formData.imgUrlList)
            this.$emit('submit-btn-handle')
            this.imgIndex = 0
          } else {
            this.$message({ type: 'warning', message: '请选填必填项' })
            return false
          }
        })
      },
      // 取消按钮
      cancelHandel () {
        this.dialogPopupVisible = false
      },
      // 照片上传成功的回调
      handleUploadSuccess (res, file, type) {
        this.formData.url = URL.createObjectURL(file.raw)
      },
      closeDialog () {
        this.$emit('closeDialog')
      },
      // 上传前的过滤
      beforeUpload (file) {
        this.dialogBtnVisible = true
        const isJPG = imageFileLimit.includes(
          file.name.replace(/.+\./, '').toLowerCase()
        )
        if (this.formData.type == 'other') {
          if (this.formData.uploadFileType == '2') {
            if (!'.png,.jpg,.jpeg'.includes(file.name.replace(/.+\./, '').toLowerCase())) {
              this.$message.error('上传证照只能是图片!')
              this.dialogBtnVisible = false
              return false
            }
          } else {
            if (!'.pdf'.includes(file.name.replace(/.+\./, '').toLowerCase())) {
              this.$message.error('上传证照只能是PDF格式!')
              this.dialogBtnVisible = false
              return false
            }
          }
        } else {
          if (!isJPG) {
            this.$message.error('上传证照只能是图片或者PDF格式!')
            this.dialogBtnVisible = false
            return false
          }
        }

        // 文件大小限制
        const isLt3M = file.size / 1024 / 1024 < this.fileSize
        if (!isLt3M) {
          this.$message.error(`上传资源大小不能超过 ${this.fileSize}MB!`)
          this.dialogBtnVisible = false
          return false
        }
      },
      // 上传接口
      httpUpload ({ file }) {
        // 上传逻辑
        let fd = new FormData()
        fd.append('file', file)
        this.$axios({
          method: 'post',
          url: fileUpload,
          headers: { 'Content-Type': 'multipart/form-data' },
          data: fd
        })
          .then(res => {
            const { data } = res
            if (!Number(data.code)) {
              this.$message.success('资源上传成功')
              // 赋值上传后的地址给文档
              console.log(this.formData.type)
              console.log(this.formData.uploadFileType)
              if (this.formData.type == 'other' && this.formData.uploadFileType == '2') {
                let curIndex = this.formData.imgUrlList.length
                this.formData.imgUrlList.push([
                  res.data.payload,
                  curIndex.toString()
                ])
              } else {
                this.formData.url = res.data.payload
              }
              console.log(this.formData.imgUrlList)
            } else {
              this.$message.error(data.msg)
            }
          })
          .catch(error => {
            this.$message.error(error.message)
          })
          .finally(() => {
            // 弹层按钮可点击
            this.dialogBtnVisible = false
          })
      }
    }
  }
</script>
<style lang="less">
  @import '~@assets/var.less';

  .dialog-licence-box {
    .imgUrlList-box{
      max-height: 300px;
      overflow: auto;
      margin: 0 60px;
      .box-item{
        position: relative;
        overflow: hidden;
        background-color: #fff;
        border: 1px solid #c0ccda;
        border-radius: 6px;
        box-sizing: border-box;
        width: 112px;
        height: 112px;
        margin: 0 8px 8px 0;
        display: inline-block;
        .box-item__item-actions{
          position: absolute;
          width: 100%;
          height: 100%;
          left: 0;
          top: 0;
          cursor: default;
          text-align: center;
          color: #fff;
          opacity: 0;
          font-size: 20px;
          background-color: rgba(0,0,0,.5);
          transition: opacity .3s;
          .box-item__item-delete{
            position: absolute;
            top: 50%;
            left: 50%;
            margin-top: -25px;
            margin-left: -6px;
          }
        }
      }
      .box-item:hover .box-item__item-actions{
        opacity: 0.7;
      }

    }
    .other-box{
      margin: 20px 55px;
    }
    .el-input {
      width: 320px;
    }

    .el-textarea {
      width: 320px;
    }

    .date-picker {
      .el-input {
        width: 144px;
      }
    }

    .iconpdf {
      font-size: 100px;
      line-height: 100px;
    }

    .line-height {
      .el-form-item__label {
        line-height: 16px;
      }
    }

    .dialog-upload {
      width: 211px;
      height: 134px;
      display: flex;
      align-items: center;
      justify-content: center;

      .el-upload {
        height: 100%;

        .el-image {
          height: 100%;
        }
      }
      .avatar-box {
        width: 120px;
        height: 120px;
      }
      .tip-box {
        display: flex;
        flex-direction: column;
        align-items: center;

        .tip-uplader {
          width: 60px;
          height: 60px;
          border-radius: 50%;
          border: @defaultBorder;
          display: flex;
          justify-content: center;
          align-items: center;
        }
      }
    }
  }
</style>
